﻿// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Interactivity;
using CPN.PJN.Silverlight.UI.Interactions.Interactivity;

namespace CPN.PJN.Silverlight.UI.Interactions.Actions
{
    /// <summary>
    /// Sets or increments a property when triggered.
    /// </summary>
    public class SetProperty : TargetedTriggerAction<FrameworkElement>
    {
        public static readonly DependencyProperty PropertyNameProperty =
            DependencyProperty.Register("PropertyName", typeof(string), typeof(SetProperty),
            new PropertyMetadata(null));

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(SetProperty),
            new PropertyMetadata(null));

        #region Properties

        // it might be possible to do
        //public Binding TargetBinding { get; set; }

        [Category("Common Properties")]
        public string PropertyName
        {
            get { return Convert.ToString(GetValue(PropertyNameProperty)); }
            set { SetValue(PropertyNameProperty, value); }
        }

        [Category("Common Properties")]
        [CustomPropertyValueEditor(CustomPropertyValueEditor.PropertyBinding)]
        public Object Value
        {
            get { return GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        #endregion

        #region Trigger Related

        protected override void Invoke(object parameter)
        {
            if (string.IsNullOrEmpty(this.PropertyName) || this.AssociatedObject == null) return;

            // we set the value
            var _propertyInfo = this.AssociatedObject.GetType().GetProperty(this.PropertyName);
            if (_propertyInfo == null || !_propertyInfo.CanWrite) return;

            // else we convert and set the value
            var _value = Value != null ? ConverterHelper.ConvertToType(Value, _propertyInfo.PropertyType) : null;
            _propertyInfo.SetValue(this.AssociatedObject, _value, null);
        }

        #endregion
    }
}
